// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

import { Palette, Button } from "std-widgets.slint";
import { WindowGlobal, WindowManager, PickerData, PickerTab, BrushMode, BrushPropertyType, WidgetMode } from "../../windowglobal.slint";
import { Api } from "../../api.slint";
import { Icons, EditorPalette, EditorSizeSettings, PickerStyles } from "../../components/styling.slint";
import { SimpleColumn } from "../../components/layout-helpers.slint";
import { DraggablePanel } from "../../components/draggable-panel.slint";
import { ColorModeAndApply } from "./floating-brush-sections/color-mode-and-apply.slint";
import { GradientPicker } from "./floating-brush-sections/gradient-ui.slint";
import { RecentColorPicker } from "floating-brush-sections/palettes.slint";
import { CssColorPicker } from "floating-brush-sections/css-color-ui.slint";


component TabIcon inherits Rectangle {
    width: 25px;
    height: self.width;

    in property <PickerTab> picker-tab;
    property <bool> is-active: picker-tab == PickerData.active-tab;

    Rectangle {
        visible: is-active;
        background: EditorPalette.text-color.with-alpha(20%);
        border-radius: EditorSizeSettings.property-border-radius;
    }

    ta := TouchArea {
        clicked => {
            PickerData.set-active-tab(picker-tab);
        }
    }

    Rectangle {
        width: 15px;
        height: self.width;
        opacity: is-active ? 1 : 0.5;

        Rectangle {
            border-radius: 2px;
            border-width: 1px;
            border-color: EditorPalette.text-color;

            @children
        }
    }
}

component BrushTypeSelector {
    width: 100%;
    height: 100%;

    in property <bool> supports-gradient;

    HorizontalLayout {
        padding-left: EditorSizeSettings.small-margin;
        alignment: start;

        TabIcon {
            y: (parent.height - self.height) / 2;
            picker-tab: PickerTab.color;

            Rectangle {
                Rectangle {
                    width: parent.width - 4px;
                    height: parent.height - 4px;
                    border-width: 1px;
                    border-color: EditorPalette.text-color;
                    background: lightgrey;
                }
            }
        }

        if supports-gradient: TabIcon {
            y: (parent.height - self.height) / 2;
            picker-tab: PickerTab.gradient;

            Rectangle {
                Rectangle {
                    width: parent.width - 4px;
                    height: parent.height - 4px;
                    background: @linear-gradient(90deg, EditorPalette.text-color 0%, transparent 100%);
                }
            }
        }

        TabIcon {
            y: (parent.height - self.height) / 2;
            picker-tab: PickerTab.css-color;

            Rectangle {
                Text {
                    font-family: "Inter";
                    font-size: 6px;
                    color: EditorPalette.text-color;
                    text: "CSS";
                    font-weight: 600;
                }
            }
        }

        TabIcon {
            y: (parent.height - self.height) / 2;
            picker-tab: PickerTab.globals;

            Rectangle {
                Text {
                    font-family: "Inter";
                    font-size: 8px;
                    color: EditorPalette.text-color;
                    text: "G";
                    font-weight: 800;
                }
            }
        }
    }
}

component VerticalSpacer {
    width: 100%;
    height: EditorSizeSettings.small-margin;
}

component HsvPicker inherits SimpleColumn {
    saturation-value-holder := Rectangle {
        height: self.width * 0.75;
        saturation-value := Rectangle {
            width: parent.width - (EditorSizeSettings.standard-margin * 2);
            height: parent.height - (EditorSizeSettings.standard-margin * 2);

            Rectangle {
                border-radius: 6px;
                clip: true;
                hue := Rectangle {
                    background: hsv(PickerData.hue, 1, 1);
                }

                sat := Rectangle {
                    background: @linear-gradient(90deg, white 0%, transparent 100%);
                }

                val := Rectangle {
                    background: @linear-gradient(0deg, black 0%, transparent 100%);
                }

                Rectangle {
                    border-radius: parent.border-radius;
                    border-width: 1px;
                    border-color: EditorPalette.text-color.with-alpha(10%);
                }

                TouchArea {
                    moved => {
                        if self.has-hover {
                            PickerData.saturation = clamp(self.mouse-x / self.width, 0, 1);
                            PickerData.value = clamp(1 - (self.mouse-y / self.height), 0, 1);
                        }
                    }
                    changed pressed => {
                        if self.pressed {
                            PickerData.saturation = self.mouse-x / self.width;
                            PickerData.value = 1 - (self.mouse-y / self.height);
                        }
                    }
                }
            }

            sv-picker := Rectangle {
                x: 1px + (saturation-value.width - 3px) * PickerData.saturation;
                y: 1px + (saturation-value.height - 3px) * (1 - PickerData.value);
                width: 1px;
                height: 1px;
                Rectangle {
                    width: 12px;
                    height: 12px;
                    border-radius: self.width / 2;
                    background: white;
                    drop-shadow-blur: 5px;
                    drop-shadow-offset-y: 2px;
                    drop-shadow-color: #000000b4;
                }

                Rectangle {
                    width: 8px;
                    height: 8px;
                    border-radius: self.width / 2;
                    background: hsv(PickerData.hue, PickerData.saturation, PickerData.value);
                }
            }
        }
    }

    hsva-controls := Rectangle {
        width: 100%;
        height: 56px;
        // The following properties are used to size the hue picker and control the
        // thumb to now go past the visual bounds. But the TouchArea is intentionally larger
        // to be usable.
        property <length> main-width: root.width - (EditorSizeSettings.standard-margin * 2) - main-height;
        property <length> main-height: 16px;
        property <length> rounded-end-width: main-height / 2;
        VerticalLayout {
            spacing: 12px;
            Rectangle {
                width: 100%;
                height: 16px;
                hue-picker := Rectangle {
                    x: EditorSizeSettings.standard-margin;
                    width: root.width - (EditorSizeSettings.standard-margin * 2);
                    height: main-height;
                    TouchArea {
                        moved => {
                            if self.has-hover {
                                if self.mouse-x < main-height / 2 {
                                    PickerData.hue = 0;
                                } else {
                                    PickerData.hue = 359 * clamp((self.mouse-x - rounded-end-width) / (self.width - main-height), 0, 1);
                                }
                            }
                        }
                        changed pressed => {
                            if self.mouse-x < main-height / 2 {
                                PickerData.hue = 0;
                            } else {
                                PickerData.hue = 359 * clamp((self.mouse-x - rounded-end-width) / (self.width - main-height), 0, 1);
                            }
                        }
                    }

                    Rectangle {
                        border-radius: self.height / 2;
                        clip: true;
                        HorizontalLayout {
                            Rectangle {
                                width: self.height / 2;
                                height: hue-picker.height;
                                background: #ff0000;
                            }

                            Rectangle {
                                width: main-width;
                                height: hue-picker.height;
                                background: @linear-gradient(90deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
                            }

                            Rectangle {
                                width: self.height / 2;
                                height: hue-picker.height;
                                background: #ff0000;
                            }
                        }

                        Rectangle {
                            border-radius: parent.border-radius;
                            border-width: 1px;
                            border-color: EditorPalette.text-color;
                            opacity: 10%;
                        }
                    }

                    Rectangle {
                        x: rounded-end-width + (main-width * (PickerData.hue / 360));
                        width: 0;
                        height: 0;
                        Rectangle {
                            width: 16px;
                            height: 16px;
                            border-radius: self.width / 2;
                            background: white;
                            drop-shadow-blur: 5px;
                            drop-shadow-offset-y: 1px;
                            drop-shadow-color: #000000;
                        }

                        Rectangle {
                            width: 8px;
                            height: 8px;
                            border-radius: self.width / 2;
                            background: hsv(PickerData.hue, 1, 1);
                        }
                    }
                }
            }

            Rectangle {
                width: 100%;
                height: 16px;
                Rectangle {
                    x: EditorSizeSettings.standard-margin;
                    width: main-width + main-height;
                    height: main-height;
                    Rectangle {
                        border-radius: self.height / 2;
                        clip: true;

                        HorizontalLayout {
                            Rectangle {
                                width: self.height / 2;
                                height: hue-picker.height;
                                background: white;
                            }

                            Rectangle {
                                width: main-width;
                                height: hue-picker.height;
                                background: white;
                            }

                            Rectangle {
                                width: self.height / 2;
                                height: hue-picker.height;
                            }
                        }

                        Image {
                            x: 0;
                            width: main-width + (self.height / 2);
                            height: 100%;
                            vertical-alignment: top;
                            horizontal-alignment: left;
                            source: Icons.checkerboard-mini;
                            vertical-tiling: repeat;
                            horizontal-tiling: repeat;
                            colorize: #e1e1e1;
                        }

                        HorizontalLayout {
                            Rectangle {
                                width: self.height / 2;
                                height: hue-picker.height;
                            }

                            Rectangle {
                                width: main-width;
                                height: hue-picker.height;
                                background: @linear-gradient(-90deg, hsv(PickerData.hue, PickerData.saturation, PickerData.value, 1), transparent);
                            }

                            Rectangle {
                                width: self.height / 2;
                                height: hue-picker.height;
                                background: hsv(PickerData.hue, PickerData.saturation, PickerData.value, 1);
                            }
                        }

                        Rectangle {
                            border-radius: parent.border-radius;
                            border-width: 1px;
                            border-color: EditorPalette.text-color;
                            opacity: 10%;
                        }
                    }

                    Rectangle {
                        x: rounded-end-width + (main-width * (PickerData.alpha / 100));
                        width: 0;
                        height: 0;
                        Rectangle {
                            width: 16px;
                            height: 16px;
                            border-radius: self.width / 2;
                            background: white;
                            drop-shadow-blur: 5px;
                            drop-shadow-offset-y: 1px;
                            drop-shadow-color: #000000;
                        }

                        Rectangle {
                            width: 8px;
                            height: 8px;
                            border-radius: self.width / 2;
                            background: PickerData.current-color;
                        }
                    }

                    TouchArea {
                        moved => {
                            if self.has-hover {
                                if self.mouse-x < rounded-end-width {
                                    PickerData.alpha = 0;
                                } else {
                                    PickerData.alpha = (100 * clamp((self.mouse-x - rounded-end-width) / (self.width - main-height), 0, 1)).round();
                                }
                            }
                        }
                        changed pressed => {
                            if self.mouse-x < rounded-end-width {
                                PickerData.alpha = 0;
                            } else {
                                PickerData.alpha = (100 * clamp((self.mouse-x - rounded-end-width) / (self.width - main-height), 0, 1)).round();
                            }
                        }
                    }
                }
            }
        }
    }
}

component ColorPicker inherits DraggablePanel {
    // Is the picker being used to edit (property tab) or preview (data tab)
    in property <WidgetMode> widget-mode: edit;
    // Is the property type color or a brush. Don't show  gradient picker for colors
    in property <BrushPropertyType> picker-mode: brush;
    // The specific current brush type (color, linear, radial, etc)
    in-out property <BrushMode> brush-mode: color;
    property <PickerTab> active-tab: widget-mode == WidgetMode.color-stop ? PickerTab.color : PickerData.active-tab;

    property <bool> show-recent: widget-mode == WidgetMode.color-stop || PickerData.active-tab == PickerTab.color;

    callback close <=> t-close.clicked;

    width: PickerStyles.picker-width;

    title := Rectangle {
        width: 100%;
        height: 40px;

        if widget-mode != WidgetMode.color-stop: BrushTypeSelector {
            supports-gradient: picker-mode == BrushPropertyType.brush;
        }

        Rectangle {
            x: parent.width - self.width - 5px;
            width: 25px;
            height: self.width;
            background: t-close.has-hover ? EditorPalette.section-color : transparent;
            border-radius: EditorSizeSettings.property-border-radius;

            t-close := TouchArea { }

            Image {
                source: Icons.close;
                colorize: EditorPalette.text-color;
            }
        }

        Rectangle {
            width: 100%;
            height: 1px;
            x: 0;
            y: parent.height - self.height;
            background: EditorPalette.divider-color;
        }
    }

    if active-tab == PickerTab.color: HsvPicker { }

    if active-tab == PickerTab.color: color-apply := ColorModeAndApply {
        widget-mode: root.widget-mode;

        clear-focus-panel => {
            root.clear-focus-panel();
        }
    }

    if active-tab == PickerTab.gradient: GradientPicker {
        widget-mode <=> root.widget-mode;
        clear-focus-panel => {
            root.clear-focus-panel();
        }
    }

    if show-recent: VerticalSpacer { }

    if show-recent: RecentColorPicker {
        recent-colors <=> Api.recent-colors;
    }

    if active-tab == PickerTab.css-color: CssColorPicker {
        filter-text: "^Colors. '%is_brush:yes ";
    }

    if active-tab == PickerTab.color && widget-mode == WidgetMode.edit: Button {
        x: EditorSizeSettings.standard-margin;
        width: 100px;
        text: "Apply";
        changed pressed => {
            if self.pressed {
                root.clear-focus-panel();
            }
        }
        clicked => {
            Api.add-recent-color(PickerData.current-color);
            if PickerData.current-color.to-hsv().alpha == 1 {
                WindowManager.apply-current-value("#\{Api.color-to-data(PickerData.current-color).short-text}")
            } else {
                WindowManager.apply-current-value(Api.color-to-data(PickerData.current-color).text);
            }
        }
    }

    if active-tab == PickerTab.globals: CssColorPicker {
        property <string> filter-brush-and-color: "!^Colors. '%is_brush:yes ";
        property <string> filter-color-only: "!^Colors. '%kind:Color ";
        filter-text: picker-mode == BrushPropertyType.brush ? filter-brush-and-color : filter-color-only;
    }

    footer := Rectangle {
        width: 100%;
        height: EditorSizeSettings.small-margin;
    }
}

export component ColorPickerView {
    width: 100%;
    height: 100%;

    in property <length> initial-x: 0;
    in property <length> initial-y: 0;
    in property <bool> color-stop-mode: false;
    callback close();

    color-picker := ColorPicker {
        x: root.initial-x;
        y: root.initial-y;
        widget-mode: color-stop-mode ? WidgetMode.color-stop : WindowManager.widget-mode;
        picker-mode: color-stop-mode ? BrushPropertyType.color : PickerData.picker-mode;
        brush-mode: color-stop-mode ? BrushMode.color : PickerData.brush-mode;
        close => {
            root.close();
        }
    }
}
